package org.nnxy.foodboot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.nnxy.foodboot.entity.*;
import org.nnxy.foodboot.mapper.RecipeMapper;
import org.nnxy.foodboot.mapper.RecommendationRecordMapper;
import org.nnxy.foodboot.service.RecipeFeatureService;
import org.nnxy.foodboot.service.RecipeService;
import org.nnxy.foodboot.service.RecommendationService;
import org.nnxy.foodboot.service.UserFavoriteService;
import org.nnxy.foodboot.service.UserPreferenceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;
import java.util.function.Function;

@Service
public class RecommendationServiceImpl implements RecommendationService {

    @Autowired
    private RecipeService recipeService;
    
    @Autowired
    private RecipeFeatureService recipeFeatureService;
    
    @Autowired
    private UserPreferenceService userPreferenceService;
    
    @Autowired
    private UserFavoriteService userFavoriteService;
    
    @Autowired
    private RecommendationRecordMapper recommendationRecordMapper;
    
    @Autowired
    private RecipeMapper recipeMapper;

    @Override
    public List<Recipe> getHealthBasedRecommendations(Integer userId, Integer limit) {
        // 获取用户健康偏好
        UserPreference userPreference = userPreferenceService.getUserPreferenceByUserId(userId);
        if (userPreference == null || userPreference.getHealthNeeds() == null) {
            return Collections.emptyList();
        }
        
        // 获取符合健康标签的食谱ID
        List<Integer> recipeIds = recipeFeatureService.getRecipeIdsByHealthTag(userPreference.getHealthNeeds(), limit);
        
        // 获取食谱详情
        return getRecipesByIds(recipeIds);
    }

    @Override
    public List<Recipe> getTasteBasedRecommendations(Integer userId, Integer limit) {
        // 获取用户口味偏好
        UserPreference userPreference = userPreferenceService.getUserPreferenceByUserId(userId);
        if (userPreference == null || userPreference.getTastePreference() == null) {
            return Collections.emptyList();
        }
        
        // 获取符合口味偏好的食谱ID
        List<Integer> recipeIds = recipeFeatureService.getRecipeIdsByTasteProfile(userPreference.getTastePreference(), limit);
        
        // 获取食谱详情
        return getRecipesByIds(recipeIds);
    }

    @Override
    public List<Recipe> getUserPreferenceBasedRecommendations(Integer userId, Integer limit) {
        // 获取用户收藏的食谱
        List<UserFavorite> userFavorites = userFavoriteService.getUserFavoritesByUserId(userId);
        if (userFavorites == null || userFavorites.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 获取用户喜欢的食谱ID列表
        List<Integer> favoriteRecipeIds = userFavorites.stream()
                .map(UserFavorite::getRecipeId)
                .collect(Collectors.toList());
        
        // 获取这些食谱的特征
        List<RecipeFeature> features = new ArrayList<>();
        for (Integer recipeId : favoriteRecipeIds) {
            RecipeFeature feature = recipeFeatureService.getRecipeFeatureByRecipeId(recipeId);
            if (feature != null) {
                features.add(feature);
            }
        }
        
        // 计算最常见的菜系和口味
        Map<String, Integer> cuisineCount = new HashMap<>();
        Map<String, Integer> tasteCount = new HashMap<>();
        
        for (RecipeFeature feature : features) {
            String cuisine = feature.getCuisineType();
            String taste = feature.getTasteProfile();
            
            if (cuisine != null) {
                cuisineCount.put(cuisine, cuisineCount.getOrDefault(cuisine, 0) + 1);
            }
            
            if (taste != null) {
                tasteCount.put(taste, tasteCount.getOrDefault(taste, 0) + 1);
            }
        }
        
        // 获取最热门的菜系和口味
        String topCuisine = getTopEntry(cuisineCount);
        String topTaste = getTopEntry(tasteCount);
        
        // 基于最喜欢的菜系和口味获取推荐
        List<Integer> cuisineBasedIds = recipeFeatureService.getRecipeIdsByCuisineType(topCuisine, limit / 2);
        List<Integer> tasteBasedIds = recipeFeatureService.getRecipeIdsByTasteProfile(topTaste, limit / 2);
        
        // 合并并去重
        Set<Integer> recommendedIds = new HashSet<>();
        recommendedIds.addAll(cuisineBasedIds);
        recommendedIds.addAll(tasteBasedIds);
        
        // 排除已收藏的食谱
        recommendedIds.removeAll(favoriteRecipeIds);
        
        // 转换为列表并限制数量
        List<Integer> finalIds = new ArrayList<>(recommendedIds);
        if (finalIds.size() > limit) {
            finalIds = finalIds.subList(0, limit);
        }
        
        // 获取食谱详情
        return getRecipesByIds(finalIds);
    }

    @Override
    public List<Recipe> getSimilarRecipes(Integer recipeId, Integer limit) {
        // 获取当前食谱的特征
        RecipeFeature currentFeature = recipeFeatureService.getRecipeFeatureByRecipeId(recipeId);
        if (currentFeature == null) {
            return Collections.emptyList();
        }
        
        // 根据菜系和口味找相似食谱
        List<Integer> cuisineBasedIds = recipeFeatureService.getRecipeIdsByCuisineType(currentFeature.getCuisineType(), limit);
        List<Integer> tasteBasedIds = recipeFeatureService.getRecipeIdsByTasteProfile(currentFeature.getTasteProfile(), limit);
        
        // 合并并去重
        Set<Integer> similarIds = new HashSet<>();
        similarIds.addAll(cuisineBasedIds);
        similarIds.addAll(tasteBasedIds);
        
        // 排除当前食谱
        similarIds.remove(recipeId);
        
        // 转换为列表并限制数量
        List<Integer> finalIds = new ArrayList<>(similarIds);
        if (finalIds.size() > limit) {
            finalIds = finalIds.subList(0, limit);
        }
        
        // 获取食谱详情
        return getRecipesByIds(finalIds);
    }

    @Override
    public List<Recipe> getCuisineTypeBasedRecommendations(String cuisineType, Integer limit) {
        // 获取特定菜系的食谱ID
        List<Integer> recipeIds = recipeFeatureService.getRecipeIdsByCuisineType(cuisineType, limit);
        
        // 获取食谱详情
        return getRecipesByIds(recipeIds);
    }

    @Override
    public Map<String, List<Recipe>> getPersonalizedRecommendations(Integer userId, Integer limit) {
        Map<String, List<Recipe>> recommendations = new HashMap<>();
        
        // 获取各种推荐
        List<Recipe> healthBased = getHealthBasedRecommendations(userId, limit);
        List<Recipe> tasteBased = getTasteBasedRecommendations(userId, limit);
        List<Recipe> preferenceBased = getUserPreferenceBasedRecommendations(userId, limit);
        
        // 添加到结果映射
        if (!healthBased.isEmpty()) {
            recommendations.put("healthBased", healthBased);
        }
        
        if (!tasteBased.isEmpty()) {
            recommendations.put("tasteBased", tasteBased);
        }
        
        if (!preferenceBased.isEmpty()) {
            recommendations.put("preferenceBased", preferenceBased);
        }
        
        // 如果所有推荐都为空，添加随机推荐
        if (recommendations.isEmpty()) {
            List<Recipe> randomRecipes = getRandomRecipes(limit);
            recommendations.put("random", randomRecipes);
        }
        
        return recommendations;
    }

    @Override
    public List<Recipe> getPopularRecipes(Integer limit) {
        if (limit == null || limit <= 0) {
            return Collections.emptyList();
        }
        
        // 根据浏览量、收藏量或评分获取热门食谱
        // 这里简化为直接查询食谱表并按创建时间降序排序
        LambdaQueryWrapper<Recipe> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Recipe::getCreateTime)
                .last("LIMIT " + limit);
        
        return recipeService.list(queryWrapper);
    }
    
    @Override
    public List<Recipe> getNewRecipes(Integer limit) {
        if (limit == null || limit <= 0) {
            return Collections.emptyList();
        }
        
        // 获取最新发布的食谱
        LambdaQueryWrapper<Recipe> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Recipe::getCreateTime)
                .last("LIMIT " + limit);
        
        return recipeService.list(queryWrapper);
    }
    
    // 辅助方法：根据ID列表获取食谱
    private List<Recipe> getRecipesByIds(List<Integer> recipeIds) {
        if (recipeIds == null || recipeIds.isEmpty()) {
            return Collections.emptyList();
        }
        
        LambdaQueryWrapper<Recipe> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Recipe::getId, recipeIds);
        return recipeService.list(queryWrapper);
    }
    
    // 辅助方法：获取映射中最多的条目
    private String getTopEntry(Map<String, Integer> countMap) {
        if (countMap == null || countMap.isEmpty()) {
            return null;
        }
        
        return countMap.entrySet().stream()
                .max(Map.Entry.comparingByValue())
                .map(Map.Entry::getKey)
                .orElse(null);
    }
    
    // 辅助方法：获取随机食谱
    private List<Recipe> getRandomRecipes(Integer limit) {
        if (limit == null || limit <= 0) {
            return Collections.emptyList();
        }
        
        // 获取随机食谱的实现
        // 简化实现：获取最新的一些食谱并随机打乱顺序
        LambdaQueryWrapper<Recipe> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Recipe::getCreateTime)
                .last("LIMIT " + (limit * 2)); // 获取更多的结果，以便随机选择
        
        List<Recipe> recipes = recipeService.list(queryWrapper);
        if (recipes.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 随机打乱顺序
        Collections.shuffle(recipes);
        
        // 限制返回数量
        return recipes.size() <= limit ? recipes : recipes.subList(0, limit);
    }

    /**
     * 用户推荐食谱实现
     */
    @Override
    public List<Recipe> getUserRecommendations(Integer userId, Integer limit) {
        // 先从推荐记录表中查询该用户的推荐
        List<RecommendationRecord> records = recommendationRecordMapper.selectList(
            new LambdaQueryWrapper<RecommendationRecord>()
                .eq(RecommendationRecord::getUserId, userId)
                .orderByDesc(RecommendationRecord::getRecommendationTime)
                .last("LIMIT " + limit)
        );
        
        // 如果没有推荐记录，返回空列表
        if (records.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 根据推荐记录获取食谱详情
        List<Integer> recipeIds = records.stream()
            .map(RecommendationRecord::getRecipeId)
            .collect(Collectors.toList());
        
        List<Recipe> recipes = recipeMapper.selectBatchIds(recipeIds);
        
        // 保持推荐顺序
        Map<Integer, Recipe> recipeMap = recipes.stream()
            .collect(Collectors.toMap(Recipe::getId, Function.identity()));
        
        return records.stream()
            .map(record -> recipeMap.get(record.getRecipeId()))
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
    }

    /**
     * 检查用户是否有推荐数据
     */
    @Override
    public boolean hasUserRecommendations(Integer userId) {
        Integer count = Math.toIntExact(recommendationRecordMapper.selectCount(
                new LambdaQueryWrapper<RecommendationRecord>()
                        .eq(RecommendationRecord::getUserId, userId)
                        .last("LIMIT 1")
        ));
        return count > 0;
    }
} 